/*!
 自定义error，便于解决Result E问题
- thiserror的属性宏 error，from
- anyhow的函数宏 anyhow!, bail!
- 定制axum handle出错展示页面： impl IntoResponse for MyError {... }
- 在定制错误中，针对特定错误的页面直接跳转，如NotLogin

*/
use anyhow;
use axum::response::{Html, IntoResponse, Response};
use serde_json;
use std::fmt::Debug;
use thiserror::Error;
use axum::{
    response::{Redirect}
};

#[allow(dead_code)]
#[derive(Debug, Error)]
pub enum MyError {
    #[error("Error: '{0}'")]
    AnyErr(#[from] anyhow::Error),
    #[error("Error: '{0}'")]
    IoErr(#[from] std::io::Error),
    #[error("Error: '{0}'")]
    SerdeErr(#[from] serde_json::error::Error),
    //#[error("Error: '{0}'")]
    #[error("{0}")]
    NotLogin(String),
    #[error("{0}")]
    GotoLogin(String),
    #[error("{0}")]
    Shutdown(String),
    #[error("{0}")]
    ConnectRefused(String),
    #[error("{0}")]
    Terminated(String),
    #[error("{0}")]
    SubscribeErr(String),
    //HttpHeaderErr(#[from] axum::http::Error),
}
/* // 可以直接通过from宏完成，如上： IoErr(#[from] std::io::Error),
impl From<std::io::Error> for MyError {
    fn from(err: std::io::Error) -> MyError {
        MyError::StrErr( err.to_string() )
    }
}
*/
impl IntoResponse for MyError {
    fn into_response(self) -> Response {
        match self {
            MyError::NotLogin(str) => {

                let mut ret = String::new();
                ret.push_str(
                    r#"<html><head><title>友情提醒</title></head>
        <h1 align="center"> YOU ARE NOT LOGIN NOW ！ </h1>
        <body><BR><div align="center">"#,
                );
                ret.push_str(r#"<a href="/fswork/xlogin?next="#);
                ret.push_str( str.as_str() );
                ret.push_str(r#""> 现在就去登录!</a></div></body></html>"#);
                Html(ret).into_response()
            },
            MyError::GotoLogin(str) => {
                let goto = format!("/fswork/xlogin?next={}", str);
                Redirect::to(goto.as_str()).into_response()                
            },
            _ => {
                let mut ret = String::new();
                ret.push_str(
                    r#"<html><head><title>Warnning</title></head>
        <h1 align="center">help tips</h1>
        <body><BR><div align="center">"#,
                );
                ret.push_str(r#"<span style="color:red">"#);
                ret.push_str(self.to_string().as_str());
                ret.push_str("</span></div></body></html>");
                Html(ret).into_response()
            },
        }
    }
}
